/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Network;

import java.net.*;
import java.io.*;
import com.thoughtworks.xstream.*;
import GameLogic.*;

/**
 *
 * @author Martin
 */
public class Server implements Serializable
{
    public static ServerSocket server;
    public static Socket[] socket;
    public static BufferedInputStream[] in;
    public static BufferedOutputStream[] out;

    public Server()
    {
    }

    //Test-Main
    public static void main( String[] args )
    {
        Player player = new Player();
        Head head = new Head(2,3);
        createServer(1234);
        accept();
        send( 0 , head );
        close();
    }

    public static void createServer( int port )
    {

        try
        {
            System.out.println("creating Server...");
            server = new ServerSocket( port );
            socket = new Socket[12];
            in = new BufferedInputStream[12];
            out = new BufferedOutputStream[12];
            System.out.println("\tServer created");
            System.out.println();
        }
        catch( Exception e )
        {
            System.out.println( "in createServer() ; " + e.toString() );
        }

    }

    public static void accept()
    {
        try
        {
            int i = 0;
            while( socket[i] != null )
            {
                ++i;
            }
            System.out.println("waiting for Client...");
            socket[i] = server.accept();
            System.out.println("\tClient accepted");
            System.out.println();
            getOutputStream(i);
            getInputStream(i);
            System.out.println("\tClient connected");
            System.out.println();
        }
        catch( Exception e )
        {
            System.out.println( "in accept() ; " + e.toString() );
        }
    }

    public static void close()
    {
        try
        {
            System.out.println("closing Server...");
            server.close();
            System.out.println("\tServer closed");
            System.out.println();
        }
        catch( Exception e )
        {
            System.out.println( "in close() ; " + e.toString() );
        }
    }

    public static void getInputStream( int i )
    {
        try
        {
            System.out.println("waiting for InputStream...");
            in[i] = new BufferedInputStream( socket[i].getInputStream() );
            System.out.println("\tInputstream opened");
            System.out.println();
        }
        catch( Exception e )
        {
            System.out.println( "in getInputStream() ; " + e.toString() );
        }
    }

    public static void getOutputStream( int i )
    {
        try
        {
            System.out.println("waiting for Outputstream...");
            out[i] = new BufferedOutputStream( socket[i].getOutputStream() );
            System.out.println("\tOutputstream opened");
            System.out.println();
        }
        catch( Exception e )
        {
            System.out.println( "in getOutputStream() ; " + e.toString() );
        }
    }

    public static void receive( int i )
    {
        try
        {
            System.out.println("receiving message...");
            byte[] data = new byte[1024];
            String str = "";
            byte b;
            b = (byte)in[i].read();
            while( b != 0 && (char)b != '#' )
            {
                str += (char)b;
            }
            if(str == "")
            {
                System.out.println("\tno message in buffer");
            }
            else
            {
                System.out.println("\tmessage received");
                data = str.getBytes();
            }
            System.out.println();
            interpret( i , data );
        }
        catch( Exception e )
        {
            System.out.println( "in receive() ; " + e.toString() );
        }
    }

    public static void send( int i , Object obj )
    {
        try
        {
            System.out.println("sending message...");

            //Neues XStream-Objekt erstellen
            XStream xstream = new XStream();
            byte[] data = new byte[1024];
            byte[] predata = new byte[64];
            
           
            predata = ( ("#" + obj.getClass().toString() + "#").getBytes() );

            //System.out.println(("#" + obj.getClass().toString() + "#").length());//

            data = (xstream.toXML( obj )).getBytes();
            out[i].write(predata , 0 , ("#" + obj.getClass().toString() + "#").length() );
            out[i].write( data , 0 , (xstream.toXML( obj )).length() );
            out[i].flush();

            //System.out.println("#" + obj.getClass().toString() + "#");//
            //System.out.println(xstream.toXML( obj ));//

            System.out.println("\tmessage sent");
            System.out.println();
        }
        catch( Exception e )
        {
            System.out.println( "in send() ; " + e.toString());
        }
    }

    public static void interpret( int i , byte[] data )
    {
        try
        {
            data = new byte[1024];
            String xml = "", predata = "";
            int f = 0;
            byte b;
            XStream xstream = new XStream();

            while(data[f] != 0)
            {
                predata += (char)data[f];
                ++f;
            }
        
            b = (byte)in[i].read();
            while( b != 0 && (char)b != '#' )
            {
                xml += (char)in[i].read();;

            }

            if( predata == "class GameLogic.Player")
            {
                Player player = (Player)xstream.fromXML( xml );
                System.out.println(player.getSnakeOrientation());
            }
            else if( predata == "class GameLogic.Head")
            {
                Head head = (Head)xstream.fromXML( xml );
                System.out.println( head.getTexture());
            }
        }
        catch( Exception e )
        {
            System.out.println( e.toString() );
        }

        /*if( data[0] != 0 )
        {
            while(data[i] != 0 )
            {
                xml += data[i];
                ++i;
            }

        //Neues XStream-Objekt erstellen
        XStream xstream = new XStream();

        //Neues Objekt aus dem XML-String erstellen
        Player player = (Player)xstream.fromXML( xml );
        System.out.println(player.getSnakeOrientation());*
        }*/
    }
}